﻿using System.Collections.Generic;
using System.Collections;
using System;
using System.IO;
using System.Globalization;
using System.Web;
using System.Collections.ObjectModel;
using System.Text;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using System.Net.Mail;
using System.Windows.Forms;

namespace CBMS.Common
{
    public class BaseFunctions
    {
        #region Define Format Valid
        public const string EXP_ACCOUNT_VALID = @"\w+([-+.@']\w+)*$";
        public const string EXP_EMAIL_VALID = @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";
        public const string EXP_URL = @"(^$)|(^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$)";
        public const string EXP_PHONE_FAX = @"^[0-9\-]{6,20}$";
        public const string EXP_ZIP = @"^[0-9\-]{6,50}$";
        public const string Admin = "Admin";

        private static string PARAM_GROUP_SEPARATOR = ".";
        private static string PARAM_DECIMAL_SEPARATOR = ",";
        public static int HourInit = 23;
        public static int MinuteInit = 59;

        public static string DrpDisplayNull = " - - - ";
        public static string DrpValueNull = "";

        #endregion Define Format Valid

        #region Define master
        public const string MEMBERSHIP_TYPEID = "000";
        public const string STAFF_ABILITY = "002";
        public const string ROLES_ADMIN = "00";
        public const string ROLES_THERAPIST = "03";
        public const string ROLES_MANAGER = "01";
        public const string ROLES_RCEPTIONIST = "02";
        public const string COUNTRY_Australia = "AU";
        #endregion

        #region Contructors
        public BaseFunctions()
        {
        }
        #endregion Contructors

        #region Define Enum Type
        #endregion

        #region Properties
        #endregion

        #region Methods
        /// <summary>
        /// Substring character from string
        /// </summary>
        /// <param name="targetText">string source</param>
        /// <param name="size">lenght need substring</param>
        /// <param name="isTrim">is trim to display alert</param>
        /// <returns>string after then substring</returns>
        public static string LeftTrim(string targetText, int size, out bool isTrim)
        {
            Encoding encoding = Encoding.GetEncoding("Shift_JIS");
            string retStr = string.Empty;
            int tagetByteSize = encoding.GetByteCount(targetText);
            byte[] arrByteText = encoding.GetBytes(targetText);
            if (tagetByteSize > size)
            {
                retStr = encoding.GetString(arrByteText, 0, size);
                targetText = targetText.Substring(0, retStr.Length) + "...";
                isTrim = true;
            }
            else
            {
                isTrim = false;
            }
            return targetText;
        }

        /// <summary>
        /// Get datetime now utc
        /// </summary>
        /// <returns>Datetime</returns>
        public static DateTime GetDateTimeUtc()
        {
            return DateTime.UtcNow.ToUniversalTime();
        }

        /// <summary>
        /// Used to format string date from CurrentCulture
        /// DD/MM/YYYY HH:SS
        /// </summary>
        /// <param name="_value"></param>
        /// <returns></returns>
        public static string FormatDateTime(DateTime dateTime, string language)
        {
            if (dateTime == null)
                return string.Empty;
            try
            {
                CultureInfo cult = CultureInfo.CreateSpecificCulture(language);
                return dateTime.ToString(cult.DateTimeFormat.ShortDatePattern + " HH:mm", cult);
            }
            catch
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// Used to format string date from CurrentCulture
        /// DD/MM/YYYY HH:SS
        /// </summary>
        /// <param name="_value"></param>
        /// <returns></returns>
        public static string FormatDateTimeTimeZone(DateTime dateTime, string language, string gmtHour)
        {
            try
            {
                CultureInfo cult = CultureInfo.CreateSpecificCulture(language);
                string strFormat = cult.DateTimeFormat.ShortDatePattern + " HH:mm:ss";
                if (gmtHour != string.Empty)
                {
                    //string strTimeZoneId = GetTimeZoneId(hour);
                    //TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(strTimeZoneId);
                    //dateTime = TimeZoneInfo.ConvertTime(dateTime.AddMinutes(hour), timeZoneInfo);
                    dateTime = dateTime.AddMinutes(int.Parse(gmtHour));
                }
                return dateTime.ToString(strFormat, cult);
            }
            catch
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// Used to format string date from CurrentCulture
        /// DD/MM/YYYY
        /// </summary>
        /// <param name="dateTime">DateTime need format</param>
        /// <param name="language">Language Culture: VN</param>
        /// <param name="gmtHour">Gmt Hour: 7</param>
        /// <returns>String Date Format</returns>
        public static string FormatShortDateTimeTimeZone(DateTime dateTime, string language, string gmtHour)
        {
            try
            {
                CultureInfo cult = CultureInfo.CreateSpecificCulture(language);
                string strFormat = cult.DateTimeFormat.ShortDatePattern + " HH:mm";
                if (gmtHour != string.Empty)
                    dateTime = dateTime.AddMinutes(int.Parse(gmtHour));
                return dateTime.ToString(strFormat, cult);
            }
            catch
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// Used to format string date from CurrentCulture
        /// DD/MM/YYYY
        /// </summary>
        /// <param name="_value"></param>
        /// <returns></returns>
        public static string FormatDateTimeShort(DateTime dateTime, string language)
        {
            if (dateTime == null)
                return string.Empty;
            try
            {
                CultureInfo cult = CultureInfo.CreateSpecificCulture(language);
                return dateTime.ToString(cult.DateTimeFormat.ShortDatePattern, cult);
            }
            catch
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// Get ContentType of file from file extension
        /// </summary>
        /// <param name="fileExtension">extension</param>
        /// <returns>ContentType: txt = text/plain </returns>
        public static string ReturnExtension(string fileExtension)
        {
            switch (fileExtension.ToLower())
            {
                case ".htm":
                case ".html":
                case ".log":
                    return "text/HTML";
                case ".txt":
                    return "text/plain";
                case ".doc":
                    return "application/ms-word";
                case ".tiff":
                case ".tif":
                    return "image/tiff";
                case ".asf":
                    return "video/x-ms-asf";
                case ".avi":
                    return "video/avi";
                case ".zip":
                    return "application/x-zip-compressed";
                case ".rar":
                    return "application/x-zip-compressed";
                case ".xls":
                case ".csv":
                    return "application/vnd.ms-excel";
                case ".xlsx":
                    return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                case ".docx":
                    return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
                case ".gif":
                    return "image/gif";
                case ".jpg":
                case "jpeg":
                    return "image/jpeg";
                case ".png":
                    return "image/png";
                case ".bmp":
                    return "image/bmp";
                case ".wav":
                    return "audio/wav";
                case ".mp3":
                    return "audio/mpeg3";
                case ".mpg":
                case "mpeg":
                    return "video/mpeg";
                case ".rtf":
                    return "application/rtf";
                case ".asp":
                    return "text/asp";
                case ".pdf":
                    return "application/pdf";
                case ".fdf":
                    return "application/vnd.fdf";
                case ".ppt":
                    return "application/mspowerpoint";
                case ".pptx":
                    return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
                case ".dwg":
                    return "image/vnd.dwg";
                case ".msg":
                    return "application/msoutlook";
                case ".xml":
                case ".sdxl":
                    return "application/xml";
                case ".xdp":
                    return "application/vnd.adobe.xdp+xml";
                default:
                    return "application/octet-stream";
            }
        }

        /// <summary>
        /// Check validate email
        /// </summary>
        /// <param name="strIn">email</param>
        /// <returns>true/false</returns>       
        public static bool IsValidEmail(string strIn)
        {
            if (String.IsNullOrEmpty(strIn))
                return false;
            return Regex.IsMatch(strIn, EXP_EMAIL_VALID, RegexOptions.IgnoreCase);
        }

        /// <summary>
        /// Check validate Account \w+([-+.@']\w+)*$; mail, @"^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$"
        /// </summary>
        /// <param name="strIn">Account</param>
        /// <returns>true/false</returns>       
        public static bool IsValidAccount(string strIn)
        {
            if (String.IsNullOrEmpty(strIn))
                return false;
            bool result = Regex.IsMatch(strIn, @"^[a-zA-Z0-9]+([-+.@']\w+)*$", RegexOptions.IgnoreCase);
            return result;
        }
        public static bool UserNameValid(string userName)
        {
            if (String.IsNullOrEmpty(userName))
                return false;
            bool result = Regex.IsMatch(userName, @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", RegexOptions.IgnoreCase);
            return result;
        }

        public static bool IsValidEmailAddress(string strIn)
        {
            if (String.IsNullOrEmpty(strIn))
                return false;
            bool result = Regex.IsMatch(strIn, @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$", RegexOptions.IgnoreCase);
            return result;
        }
        /// <summary>
        /// check float number valid
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public static bool ValidateNumber(string number)
        {
            try
            {
                double _num = Convert.ToDouble(number.Trim());
            }
            catch
            {
                return false;
            }
            return true;
        }
        /// <summary>
        /// Add commas separator to _value,
        /// round to nf floating point number
        /// </summary>
        /// <param name="_value">Formating number</param>
        /// <returns>Formated number string</returns>
        public static string NumericFormat(long _value)
        {
            if (_value < 0)
            {
                return string.Empty;
            }
            System.Globalization.NumberFormatInfo nfi = new System.Globalization.NumberFormatInfo();
            nfi.NumberDecimalDigits = 0;
            nfi.CurrencyDecimalSeparator = PARAM_DECIMAL_SEPARATOR;
            nfi.CurrencyGroupSeparator = PARAM_GROUP_SEPARATOR;
            nfi.NumberDecimalSeparator = PARAM_DECIMAL_SEPARATOR;
            nfi.NumberGroupSeparator = PARAM_GROUP_SEPARATOR;
            return _value.ToString("N", nfi);
        }

        /// <summary>
        /// Add commas separator to _value,
        /// round to nf floating point number
        /// </summary>
        /// <param name="_value">Formating number</param>
        /// <returns>Formated number string</returns>
        public static string NumericFormat(double _value)
        {
            if (_value < 0)
            {
                return string.Empty;
            }
            System.Globalization.NumberFormatInfo nfi = new System.Globalization.NumberFormatInfo();
            nfi.NumberDecimalDigits = 0;
            nfi.CurrencyDecimalSeparator = PARAM_DECIMAL_SEPARATOR;
            nfi.CurrencyGroupSeparator = PARAM_DECIMAL_SEPARATOR;
            nfi.NumberDecimalSeparator = PARAM_DECIMAL_SEPARATOR;
            nfi.NumberGroupSeparator = PARAM_DECIMAL_SEPARATOR;
            return _value.ToString("N", nfi);
        }

        /// <summary>
        /// Replace special characters
        /// </summary>
        /// <param name="characters">Characters</param>
        /// <param name="index">Index</param>
        /// <returns>String</returns>
        public static string CsvFilter(string characters)
        {
            if (characters != null)
            {
                if (characters.IndexOf('"') > -1 || characters.IndexOf(',') > -1 ||
                    characters.IndexOf('\r') > -1 || characters.IndexOf('\n') > -1 ||
                    characters.StartsWith(" ") || characters.StartsWith("\t") ||
                    characters.EndsWith(" ") || characters.EndsWith("\t"))
                {
                    if (characters.IndexOf('"') > -1)
                    {//"を""とする
                        characters = characters.Replace("\"", "\"\"");
                    }
                    characters = "\"" + characters + "\"";
                }
            }
            else
            {
                characters = "";
            }
            return characters;
        }

        public static bool IsValidSingleByte(string valueInput)
        {
            bool result = false;
            int length = valueInput.Length;
            string retStr = string.Empty;
            // Set the encode that is beeing used
            Encoding encoding = Encoding.GetEncoding("Shift_JIS");
            // Convert the input string to an array of bytes based on the above encode
            byte[] bytes = encoding.GetBytes(valueInput);
            // Get character based on the above encode
            retStr = encoding.GetString(bytes, 0, length);
            // Do the substring command with the length of encoding string
            if (valueInput.Substring(0, retStr.Length).Length == length)
            {
                result = true;
            }
            return result;
        }

        public static string Removetext(string text)
        {
            return text.Replace(":", "");
        }

        /// <summary>
        /// Kiem tra dinh dang email =true: dung dinh dang =false
        /// </summary>
        /// <param name="email"></param>
        /// <returns></returns>
        public static bool CheckFormatEmail(string email)
        {
            if (email != "")
            {
                Regex n = new Regex("^([a-zA-Z]([-.\\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\\w]*[0-9a-zA-Z]\\.)+[a-zA-Z]{2,9})$");
                Match v = n.Match(email);
                if (!v.Success || email.Length != v.Length)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Function Set focus when display error
        /// </summary>
        /// <param name="txt"></param>
        /// <param name="erro"></param>
        /// <param name="nametext"></param>
        public static void SetFocusWhenError(Control txt, bool erro, string nametext)
        {
            if (!erro && nametext != string.Empty)
            {
                txt.Focus();
                txt.Select();
            }
        }
        public static string Encrypte(string pass)
        {
            UTF32Encoding u = new UTF32Encoding();
            byte[] bytes = u.GetBytes(pass); //get original string
            MD5 md = new MD5CryptoServiceProvider(); // using md5 algorithm
            byte[] result = md.ComputeHash(bytes); // encrypted input bytes into encrypted bytes
            return Convert.ToBase64String(result); //return encrypted string
        }
        #endregion

        #region Senmail
        public static bool SendMailHtml(string _from, string _to, string _cc, string _bcc, string _subject, string _body)
        {
            System.Net.Mail.MailMessage messageUtf8 = new System.Net.Mail.MailMessage();
            string mailFrom = string.Empty;
            string fromDisplay = string.Empty;
            string[] fromArr = _from.Split("|".ToCharArray());
            if (fromArr.Length == 1)
            {
                mailFrom = fromArr[0].ToString();
                fromDisplay = "Icompany Sender";
            }

            if (fromArr.Length == 2)
            {
                mailFrom = fromArr[0].ToString();
                fromDisplay = fromArr[1].ToString();
            }

            messageUtf8.From = new MailAddress(mailFrom, fromDisplay);
            messageUtf8.ReplyToList.Add(new MailAddress(mailFrom, fromDisplay));

            /*Set MailTo*/
            string[] toArr = _to.Split(",".ToCharArray());
            foreach (string to in toArr)
            {
                string[] l = to.Split("|".ToCharArray());
                if (l.Length == 1)
                {
                    messageUtf8.To.Add(new MailAddress(l[0]));
                }
                else if (l.Length == 2)
                {
                    messageUtf8.To.Add(new MailAddress(l[0], l[1]));
                }
            }

            /*Set MailCC*/
            if (!string.IsNullOrEmpty(_cc))
            {
                string[] ccArr = _cc.Split(",".ToCharArray());
                foreach (string cc in ccArr)
                {
                    string[] l = cc.Split("|".ToCharArray());
                    if (l.Length == 1)
                    {
                        messageUtf8.CC.Add(new MailAddress(l[0]));
                    }
                    else if (l.Length == 2)
                    {
                        messageUtf8.CC.Add(new MailAddress(l[0], l[1])); ;
                    }
                }
            }

            /*Set MailCC*/
            if (!string.IsNullOrEmpty(_bcc))
            {
                string[] ccArr = _bcc.Split(",".ToCharArray());
                foreach (string cc in ccArr)
                {
                    string[] l = cc.Split("|".ToCharArray());
                    if (l.Length == 1)
                    {
                        messageUtf8.Bcc.Add(new MailAddress(l[0]));
                    }
                    else if (l.Length == 2)
                    {
                        messageUtf8.Bcc.Add(new MailAddress(l[0], l[1])); ;
                    }
                }
            }

            messageUtf8.Subject = _subject;
            messageUtf8.Body = _body.Replace("\r\n", "<br />");
            messageUtf8.IsBodyHtml = true;

            messageUtf8.SubjectEncoding = Encoding.GetEncoding(78);
            messageUtf8.BodyEncoding = Encoding.GetEncoding(78);

            AlternateView htmlView = AlternateView.CreateAlternateViewFromString(
                                       messageUtf8.Body,
                                       new System.Net.Mime.ContentType("text/html"));

            htmlView.TransferEncoding = System.Net.Mime.TransferEncoding.QuotedPrintable;
            messageUtf8.AlternateViews.Add(htmlView);


            using (System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient())
            {
                client.Host = "mail.gmail.com";//BaseFunctions.SmtpServerName;
                client.Port = 25;//BaseFunctions.SmtpPort;
                client.Timeout = 60000;
                //BaseFunctions.SmtpUserName
                if (!string.IsNullOrEmpty(""))
                {
                    //BaseFunctions.SmtpUserName, BaseFunctions.SmtpPassword
                    client.Credentials = new System.Net.NetworkCredential("", "");
                }
                //BaseFunctions.IsSmtpSSL
                if (true)
                {
                    client.EnableSsl = true;
                }
                try
                {
                    client.Send(messageUtf8);
                    messageUtf8.Dispose();
                    return true;
                }
                catch (Exception ex)
                {
                    messageUtf8.Dispose();
                    return false;
                }
            }
        }
        #endregion
    }
}